function getNoteTab(curTabId) {
	log.message('getNoteTab(' + curTabId + ')');
	
	badge.message('Wait', '#FF0000');
	state.set(state.type.gathering);
	
	var tabId = (curTabId) ? ((curTabId < 0) ? 0 : curTabId) : 0;
	
	//check if a tab id was passed in and re-use it
	if (tabId != 0) {
		c_tabs.update(tabId, {url: NOTIFICATION_URL, active: false}, function(tab) { setContentScript(tab) }); 
	} else {
		//gets all chrome windows for iteration
		chrome.windows.getAll({ populate: true }, function(windows) { 
			for (var i = 0; i < windows.length; i++) { 
				//gets all tabs within the current window iteration for iteration
				for (var j = 0; j < windows[i].tabs.length; j++) { 
					//checks if the currently loaded tab has the url we are looking for
					if (windows[i].tabs[j].url == NOTIFICATION_URL) {
						tabId = windows[i].tabs[j].id;
						c_tabs.reload(tabId, setContentScript(windows[i].tabs[j]));
					}
				}
			}
			
			//no tab was found, create it
			if (tabId == 0) {
				c_tabs.create({url: NOTIFICATION_URL, active: false}, function(tab) { setContentScript(tab) });
			}
		});
	}
}

function processDataArray(data, tabId) {
	log.message('processDataArray(item_count:' + data.length + ',  tabId:' + tabId + ')');
	
	if (globalSettings.getSetting("close_others") == true) {
		c_tabs.executeScript(tabId, {code: "closeNonEALinks()", allFrames: true});
	}
	
	if (data.length > 0) {
		saveNotesToDB(data, tabId);
		localStorage["notification_tabId"] = tabId;
		alarms.create.gather(10 * ONE_SECOND);
	} else {
		if (globalSettings.getSetting("gather_only")) {
			state.set(state.type.stopped);
			c_tabs.remove(tabId);
			var today = new Date(); 
			var t = globalSettings.getSetting("process_time"); 
			var hr = Number((t.split(' ')[0]).split(':')[0]); 
			var min = Number((t.split(' ')[0]).split(':')[1]); 
			if (t.charAt(t.length-2) == 'A') { hr += 12; if (hr >= 24) { hr = 0; } } 
			var d1 = new Date(today.getFullYear(), today.getMonth(), today.getDate(), hr, min); 
			if (d1 - today < 0) { 
				d1 = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, hr, min); 
			}
			
			alarms.create.process(Date.parse(d1) - Date.now())
		} else {
			state.set(state.type.processing);
			processCount(false);
			processItems(tabId);
		}
	}
}

function saveNotesToDB(dataArray, tabId) {
	for (var d in dataArray) {
		var i = new item();
		var linkId = i.loadFromHTML(dataArray[d].html);
		i.save();
		c_tabs.executeScript(tabId, {code: "var req = document.getElementsByClassName('E7a'); for (var i = 0; i < req.length; i++) {	if (req[i].getAttribute('link_id') == '" + linkId + "') { var link = req[i].getElementsByClassName('MFb'); simulate(link[0], 'click');}}", allFrames: true});
	}
}

function loadNotificationItems(type, callback) {
	var tmpArr = [];
	$.indexedDB(NEW_DB_NAME).objectStore("Items").index("type").each(function(v) {
		tmpArr.push(v.value);
	}, [type]).done(function() {
		tmpArr.sort(function(a, b) { 
		  if (globalSettings.getSetting("direction") == FIFO) { 
			return sortAscTime(a,b); 
		  } else { 
			return sortDescTime(a,b); 
		  } 
		});
	}).then(function() {
		callback(tmpArr);
	})
}

function processItems(tabId) {
	if (state.get() != state.type.gathering) {
		var items = [];
		
		itemDBCount(null, function(c) {
			log.message('notification item count = ' + c);
			if (c == 0) {
				state.set(state.type.stopped);
				alarms.create.refresh(globalSettings.getSetting("refresh_timer"));
				c_tabs.remove(tabId);
			} else {
				var order = globalSettings.getSetting("process_order_array").split(',');
				
				//load unknowns first
				loadNotificationItems(0, function(z) {
					loadNotificationItems(Number(order[0]), function(a) { 
						loadNotificationItems(Number(order[1]), function(b) { 
							loadNotificationItems(Number(order[2]), function(c) {
								sortedNotifications = z.concat(a, b, c);
								var item = sortedNotifications.shift();
								log.message('Executing notification ' + item.gid + ' from ' + item.uname);
								
								executeLink(item.link, tabId);
								badge.message(new String(sortedNotifications.length).toString(),  (sortedNotifications.length > 0) ? '#0000FF' : '#00FF00');
								
								$.indexedDB(NEW_DB_NAME).objectStore("Items")["delete"](item.uid).done(function() {
									$.indexedDB(NEW_DB_NAME).objectStore("History").add({ uid: item.uid, uname: item.uname, gid: item.gid, type: item.type, timestamp: item.timestamp, accepted_ts: Math.round((new Date()) / 1000) });
								});
							});
						}); 
					});
				});
			}
		});
	}
}

function executeLink(link, tabId) {
	//create a new tab using the passed in link URL
	if (tabId == 0) {
		c_tabs.create({url:link, active: false}, function(tab) { sendNextScript(tab) });
	} else {
		c_tabs.update(tabId, {url:link, active: false}, function(tab) { sendNextScript(tab) });
	}
}

function sendNextScript(tab) {
	c_tabs.executeScript(tab.id, {code: "setTimeout(function() { chrome.extension.sendMessage({action: 'next'}); }, " +  globalSettings.getSetting('close_timer') + ");"});
}

function startGathering(tabId) {
	processCount(true);
	
	getNoteTab(tabId);
}

function setContentScript(tab) {
	log.message('Adding script to tab.id: ' + tab.id);
	c_tabs.executeScript(tab.id, {file: 'js/jquery.min.js', allFrames: false, runAt: "document_end"}); 
	c_tabs.executeScript(tab.id, {file: 'js/send_links.js', allFrames: false, runAt: "document_end"}); 
	//anti stall, sometimes there is stalling when the script's aren't inserted properly or in the right frame,
	// this will cause the process to re-run.
	alarms.create.stall(20000);
}

function processCount(isReset) {
	var count = (localStorage["process_count"]) ? Number(localStorage["process_count"]) : 0;
	if (isReset) {
		count = 0;
	} else {
		count++
	}
	
	localStorage["process_count"] = count;
	return count;
}